using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using Catastrophe.Common.AttributeEx;

namespace Catastrophe.Common.FileM
{
	public class FileUtil
	{
		public List<FileInfoEntity> FileInfoCollection = new List<FileInfoEntity>();

		public static DirectoryInfo CreadDirectory(string path)
		{
			try
			{
				return Directory.CreateDirectory(path);
			}
			catch (Exception innerException)
			{
				throw new Exception("创建目录失败！", innerException);
			}
		}

		public static string CreateFile(string path)
		{
			try
			{
				if (File.Exists(path))
				{
					return "文件已经存在！";
				}
				File.Create(path);
				return "";
			}
			catch (Exception innerException)
			{
				throw new Exception("创建文件失败！", innerException);
			}
		}

		public static bool DeleteFile(string fileName)
		{
			try
			{
				if (File.Exists(fileName))
				{
					if (File.GetAttributes(fileName) == FileAttributes.Normal)
					{
						File.Delete(fileName);
					}
					else
					{
						File.SetAttributes(fileName, FileAttributes.Normal);
						File.Delete(fileName);
					}
					return true;
				}
				return false;
			}
			catch (Exception)
			{
				return false;
			}
		}

		public static bool DeleteDirectory(string path)
		{
			try
			{
				DirectoryInfo directoryInfo = new DirectoryInfo(path);
				if (directoryInfo.Exists)
				{
					DirectoryInfo[] directories = directoryInfo.GetDirectories();
					DirectoryInfo[] array = directories;
					foreach (DirectoryInfo directoryInfo2 in array)
					{
						directoryInfo2.Delete(recursive: true);
					}
					directoryInfo.Delete(recursive: true);
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		public static void DeleteFolder(string dir)
		{
			if (!Directory.Exists(dir))
			{
				return;
			}
			string[] fileSystemEntries = Directory.GetFileSystemEntries(dir);
			foreach (string text in fileSystemEntries)
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
				else
				{
					FileUtil.DeleteFolder(text);
				}
			}
		}

		public static void CopyEntireDir(string sourcePath, string destPath, bool overwrite = true)
		{
			string[] directories = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
			foreach (string text in directories)
			{
				Directory.CreateDirectory(text.Replace(sourcePath, destPath));
			}
			string[] files = Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories);
			foreach (string text2 in files)
			{
				File.Copy(text2, text2.Replace(sourcePath, destPath), overwrite);
			}
		}

		public static void MoveEntireDir(string sourcePath, string destPath)
		{
			string[] directories = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
			foreach (string text in directories)
			{
				Directory.CreateDirectory(text.Replace(sourcePath, destPath));
			}
			string[] files = Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories);
			foreach (string text2 in files)
			{
				string destFileName = FileUtil.Rename(text2, destPath);
				File.Move(text2, destFileName);
			}
		}

		public static Tuple<string, string> Rename(ref string nameWithOutE, string extend, ref int id, char tag = '-')
		{
			string text = "";
			string text2 = "";
			if (nameWithOutE.Contains(tag))
			{
				string[] source = nameWithOutE.Split(tag);
				string text3 = source.Last();
				string text4 = nameWithOutE.Replace(tag + text3, "");
				int.TryParse(text3, out id);
				id++;
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 2);
				defaultInterpolatedStringHandler.AppendFormatted(tag);
				defaultInterpolatedStringHandler.AppendFormatted(id);
				nameWithOutE = text4 + defaultInterpolatedStringHandler.ToStringAndClear();
				text = nameWithOutE + "." + extend.ToLower();
				text2 = "_N_" + text4.ToUpper() + tag + id + "_" + extend.ToUpper();
			}
			else
			{
				id++;
				text = nameWithOutE + tag + id + "." + extend.ToLower();
				text2 = "_N_" + nameWithOutE.ToUpper() + tag + id + "_" + extend.ToUpper();
				string obj = nameWithOutE;
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 2);
				defaultInterpolatedStringHandler.AppendFormatted(tag);
				defaultInterpolatedStringHandler.AppendFormatted(id);
				nameWithOutE = obj + defaultInterpolatedStringHandler.ToStringAndClear();
			}
			return new Tuple<string, string>(text, text2);
		}

		public static string Rename(string srcName)
		{
			if (srcName.Contains('.'))
			{
				string[] source = srcName.Split('.');
				string text = source.Last();
				string text2 = srcName.Replace("." + text, "");
				return "_N_" + text2.ToUpper() + "_" + text.ToUpper();
			}
			return srcName;
		}

		public static string Rename(string srcFullName, string destPath, char tag = '-')
		{
			FileInfo fileInfo = new FileInfo(srcFullName);
			string name = fileInfo.Name;
			string extension = fileInfo.Extension;
			string text = name;
			if (extension != "")
			{
				text = name.Replace(extension, "");
			}
			string text2 = Path.Combine(destPath, text + extension);
			int result = 0;
			string text3 = text;
			while (File.Exists(text2))
			{
				if (text3.Contains(tag))
				{
					string[] source = text3.Split(tag);
					string text4 = source.Last();
					string text5 = text3.Replace(tag + text4, "");
					int.TryParse(text4, out result);
					result++;
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 2);
					defaultInterpolatedStringHandler.AppendFormatted(tag);
					defaultInterpolatedStringHandler.AppendFormatted(result);
					text3 = text5 + defaultInterpolatedStringHandler.ToStringAndClear();
				}
				else
				{
					result++;
					text3 = text + tag + result;
				}
				text2 = Path.Combine(destPath, text3 + extension);
			}
			return text2;
		}

		public static List<FileInfoEntity> GetDirAllFilesWithoutContent(string srcPath, params string[] extName)
		{
			return FileUtil.GetDirAllFiles(srcPath, extName.ToList());
		}

		public static List<FileInfoEntity> GetDirAllFiles(string srcPath, List<string> extName, bool getContent = false)
		{
			if (!Directory.Exists(srcPath))
			{
				return new List<FileInfoEntity>();
			}
			List<FileInfoEntity> list = new List<FileInfoEntity>();
			string[] files = Directory.GetFiles(srcPath, "*.*", SearchOption.AllDirectories);
			string[] array = files;
			foreach (string path in array)
			{
				FileInfoEntity fileInfoEntity = FileUtil.GetFileInfoEntity(path, extName, getContent);
				if (fileInfoEntity.Type == FilePathTypeEnum.File)
				{
					list.Add(fileInfoEntity);
				}
			}
			return list;
		}

		public void GetAllInfo(string path, List<string> extName, ref int increaseId, ref int parentId)
		{
			try
			{
				string[] directories = Directory.GetDirectories(path);
				DirectoryInfo directoryInfo = new DirectoryInfo(path);
				FileInfo[] files = directoryInfo.GetFiles();
				if (files.Length == 0 && directories.Length == 0)
				{
					return;
				}
				FileInfo[] array = files;
				foreach (FileInfo fileInfo in array)
				{
					if (extName.Any((string x) => x.ToLower() == "all"))
					{
						increaseId++;
						this.AddFileInfo(fileInfo.FullName, increaseId, parentId, extName);
					}
					else if (FileUtil.CheckExtension(fileInfo.FullName, extName))
					{
						increaseId++;
						this.AddFileInfo(fileInfo.FullName, increaseId, parentId, extName);
					}
				}
				string[] array2 = directories;
				foreach (string text in array2)
				{
					increaseId++;
					parentId = increaseId;
					int parentId2 = this.FileInfoCollection.FindLast((FileInfoEntity x) => x.IsDirectory && x.FullName == path)?.QueryNodeId ?? (-1);
					this.AddFileInfo(text, increaseId, parentId2, extName);
					this.GetAllInfo(text, extName, ref increaseId, ref parentId);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private void AddFileInfo(string fileInfo, int increaseId, int parentId, List<string> extName)
		{
			FileInfoEntity fileInfoEntity = FileUtil.GetFileInfoEntity(fileInfo, extName);
			if (fileInfoEntity != null)
			{
				fileInfoEntity.QueryNodeId = increaseId;
				fileInfoEntity.QueryParentNodeId = parentId;
				this.FileInfoCollection.Add(fileInfoEntity);
			}
		}

		public static bool CheckExtension(string filePath, List<string> extName)
		{
			FileInfo fileInfo = new FileInfo(filePath);
			if (fileInfo.Extension == "")
			{
				return false;
			}
			if (extName != null && extName.FindAll((string x) => x.ToLower().IndexOf(fileInfo.Extension.ToLower(), StringComparison.Ordinal) >= 0).Count > 0)
			{
				return true;
			}
			return false;
		}

		public static long GetDirectoryLength(string path, params string[] extName)
		{
			if (!Directory.Exists(path))
			{
				return 0L;
			}
			long num = 0L;
			DirectoryInfo directoryInfo = new DirectoryInfo(path);
			FileInfo[] files = directoryInfo.GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				if (FileUtil.CheckExtension(fileInfo.FullName, extName.ToList()))
				{
					num += fileInfo.Length;
				}
			}
			DirectoryInfo[] directories = directoryInfo.GetDirectories();
			if (directories.Length != 0)
			{
				DirectoryInfo[] array = directories;
				foreach (DirectoryInfo directoryInfo2 in array)
				{
					num += FileUtil.GetDirectoryLength(directoryInfo2.FullName, extName);
				}
			}
			return num;
		}

		public static FileInfoEntity GetFileInfoEntity(string path, List<string> extName, bool getContent = false)
		{
			if (string.IsNullOrEmpty(path))
			{
				throw new ArgumentNullException();
			}
			FileInfoEntity entity = null;
			if (File.Exists(path))
			{
				FileInfo fileInfo = new FileInfo(path);
				FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(fileInfo.FullName);
				entity = new FileInfoEntity
				{
					Path = fileInfo.DirectoryName,
					NameWithoutExtension = ((fileInfo.Extension != "") ? fileInfo.Name.Replace(fileInfo.Extension, "") : fileInfo.Name),
					FullName = fileInfo.FullName,
					Extension = fileInfo.Extension,
					Name = fileInfo.Name,
					FormatName = fileInfo.Name,
					ExtensionWithoutPoint = (fileInfo.Extension.StartsWith(".") ? fileInfo.Extension.Remove(0, 1) : fileInfo.Extension),
					Size = Math.Ceiling((double)fileInfo.Length / 1024.0) + " KB",
					CreateTime = fileInfo.CreationTime.ToString(),
					ModifyTime = fileInfo.LastWriteTime.ToString(),
					Type = FilePathTypeEnum.File,
					Version = versionInfo.FileVersion,
					IsDirectory = false,
					IsExist = true,
					IsValid = true
				};
				if (extName != null && extName.FindAll((string x) => x.ToLower().IndexOf(fileInfo.Extension.ToLower(), StringComparison.Ordinal) >= 0).Count <= 0)
				{
					entity.Type = FilePathTypeEnum.NotMatch;
				}
				else if (getContent)
				{
					entity.Content = File.ReadAllBytes(fileInfo.FullName);
				}
			}
			else if (Directory.Exists(path))
			{
				DirectoryInfo directoryInfo = new DirectoryInfo(path);
				entity = new FileInfoEntity
				{
					Path = (directoryInfo.Parent?.FullName ?? directoryInfo.Root.FullName),
					Size = Math.Round((double)FileUtil.GetDirectoryLength(path, extName.ToArray()) / 1024.0, 2) + " KB",
					FullName = directoryInfo.FullName,
					Name = directoryInfo.Name,
					FormatName = directoryInfo.Name,
					CreateTime = directoryInfo.CreationTime.ToString(),
					Type = FilePathTypeEnum.Dir,
					IsDirectory = true,
					IsExist = true,
					IsValid = true
				};
			}
			else
			{
				try
				{
					entity = new FileInfoEntity
					{
						IsExist = false,
						Path = Path.GetFullPath(path),
						Name = Path.GetFileName(path),
						FormatName = Path.GetFileName(path),
						Extension = Path.GetExtension(path)
					};
					if (extName != null && extName.FindAll((string x) => x.ToLower().IndexOf(entity.Extension.ToLower(), StringComparison.Ordinal) >= 0).Count <= 0)
					{
						return new FileInfoEntity
						{
							Type = FilePathTypeEnum.NotMatch
						};
					}
					entity.NameWithoutExtension = ((entity.Extension != "") ? entity.Name.Replace(entity.Extension, "") : entity.Name);
					entity.ExtensionWithoutPoint = (entity.Extension.StartsWith(".") ? entity.Extension.Remove(0, 1) : entity.Extension);
					entity.FullName = path;
					entity.IsValid = true;
					entity.Type = FilePathTypeEnum.NotExsit;
				}
				catch
				{
					entity = new FileInfoEntity
					{
						Type = FilePathTypeEnum.NotExsit
					};
				}
			}
			return entity;
		}

		public static string GetFriendlyFileSize(double fileSize)
		{
			if (fileSize < 1024.0)
			{
				return fileSize.ToString("F1") + "Byte";
			}
			fileSize /= 1024.0;
			if (fileSize < 1024.0)
			{
				return fileSize.ToString("F1") + "KB";
			}
			fileSize /= 1024.0;
			if (fileSize < 1024.0)
			{
				return fileSize.ToString("F1") + "M";
			}
			fileSize /= 1024.0;
			return fileSize.ToString("F1") + "GB";
		}

		public static byte[] GetFile(string fileName)
		{
			FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
			BinaryReader binaryReader = new BinaryReader(fileStream);
			byte[] result = binaryReader.ReadBytes((int)fileStream.Length);
			binaryReader.Close();
			fileStream.Close();
			return result;
		}

		public static void SaveFile(byte[] file, string fileName)
		{
			string directoryName = Path.GetDirectoryName(fileName);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName ?? throw new InvalidOperationException());
			}
			FileStream fileStream = new FileStream(fileName, FileMode.Create);
			fileStream.Write(file, 0, file.Length);
			fileStream.Close();
		}

		public static void SaveFileSteam(string msg, string fileName, EncodeTypeEnum encodeTypeEnum = EncodeTypeEnum.Utf8)
		{
			try
			{
				Encoding encodeType = FileUtil.GetEncodeType(encodeTypeEnum);
				byte[] bytes = encodeType.GetBytes(msg);
				string directoryName = Path.GetDirectoryName(fileName);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName ?? throw new InvalidOperationException());
				}
				FileStream fileStream = new FileStream(fileName, FileMode.Create);
				fileStream.Write(bytes, 0, bytes.Length);
				fileStream.Close();
			}
			catch (Exception ex)
			{
				throw ex.GetBaseException();
			}
		}

		public static byte[] ImageToByte(Image image)
		{
			MemoryStream memoryStream = new MemoryStream();
			image.Save(memoryStream, ImageFormat.Gif);
			byte[] buffer = memoryStream.GetBuffer();
			memoryStream.Close();
			return buffer;
		}

		public static Image ByteToImage(byte[] buffer)
		{
			MemoryStream memoryStream = new MemoryStream(buffer);
			Image result = Image.FromStream(memoryStream);
			memoryStream.Close();
			return result;
		}

		public static void WriteBinaryFile(string fileName, string message)
		{
			Console.WriteLine("写入二进制文件信息开始。");
			FileStream fileStream = null;
			BinaryWriter binaryWriter = null;
			try
			{
				if (File.Exists(fileName))
				{
					File.Delete(fileName);
				}
				fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
				binaryWriter = new BinaryWriter(fileStream);
				byte[] bytes = Encoding.UTF8.GetBytes(message);
				binaryWriter.Write(bytes);
				binaryWriter.Close();
				fileStream.Close();
				binaryWriter = null;
				fileStream = null;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (binaryWriter != null)
				{
					try
					{
						binaryWriter.Close();
					}
					catch
					{
					}
				}
				if (fileStream != null)
				{
					try
					{
						fileStream.Close();
					}
					catch
					{
					}
				}
			}
		}

		public static Encoding GetEncodeType(EncodeTypeEnum encodeTypeEnum)
		{
			string text = BuildAttribute.GetEnumDescribe<EncodeTypeEnum>().FirstOrDefault((DescribeInfoAttribute x) => x.Name == encodeTypeEnum.ToString())?.Description;
			if (string.IsNullOrWhiteSpace(text))
			{
				throw new Exception("获取编码类型失败");
			}
			return Encoding.GetEncoding(text);
		}

		public static string ReadBinaryFile(string fileName, EncodeTypeEnum encodeTypeEnum = EncodeTypeEnum.Utf8)
		{
			FileStream fileStream = null;
			BinaryReader binaryReader = null;
			string @string;
			try
			{
				if (!File.Exists(fileName))
				{
					return string.Empty;
				}
				fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
				binaryReader = new BinaryReader(fileStream);
				int num = (int)fileStream.Length;
				byte[] array = new byte[num];
				binaryReader.Read(array, 0, array.Length);
				Encoding encodeType = FileUtil.GetEncodeType(encodeTypeEnum);
				@string = encodeType.GetString(array);
				binaryReader.Close();
				fileStream.Close();
				binaryReader = null;
				fileStream = null;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (binaryReader != null)
				{
					try
					{
						binaryReader.Close();
					}
					catch
					{
					}
				}
				if (fileStream != null)
				{
					try
					{
						fileStream.Close();
					}
					catch
					{
					}
				}
			}
			return @string;
		}

		public static string GetFileSize(string fileName)
		{
			if (File.Exists(fileName))
			{
				FileInfo fileInfo = new FileInfo(fileName);
				long length = fileInfo.Length;
				if (length > 1073741824)
				{
					return Convert.ToString(Math.Round(((double)length + 0.0) / 1073741824.0, 2)) + " GB";
				}
				if (length > 1048576)
				{
					return Convert.ToString(Math.Round(((double)length + 0.0) / 1048576.0, 2)) + " MB";
				}
				return Convert.ToString(Math.Round(((double)length + 0.0) / 1024.0, 2)) + " KB";
			}
			return null;
		}

		public static string GetTextFileContent(string fileName)
		{
			StreamReader streamReader = new StreamReader(fileName, Encoding.GetEncoding("utf-8"));
			return streamReader.ReadToEnd();
		}

		public static void SaveFile(string path, string value, EncodeTypeEnum encodeTypeEnum = EncodeTypeEnum.Utf8)
		{
			try
			{
				Encoding encodeType = FileUtil.GetEncodeType(encodeTypeEnum);
				File.WriteAllText(path, value, encodeType);
			}
			catch (Exception ex)
			{
				throw new Exception(ex.ToString());
			}
		}

		public static void RpConvertToNamesapce(ref string relativePath, string splitFlag = "\\")
		{
			if (!string.IsNullOrWhiteSpace(relativePath) && relativePath.Contains(splitFlag))
			{
				relativePath = relativePath.Replace(splitFlag, ".");
			}
		}

		public static void OpenFolder(string path)
		{
			Process.Start("explorer", path);
		}

		[Obsolete("BinaryFormatter.Serialize is obsolete")]
		public static void WriteBinarySerialize<T>(string fileName, T t) where T : class, new()
		{
			if (fileName == null)
			{
				throw new ArgumentNullException("fileName");
			}
			if (t == null)
			{
				throw new ArgumentNullException("t");
			}
			using FileStream serializationStream = new FileStream(fileName, FileMode.Create);
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			binaryFormatter.Serialize(serializationStream, t);
		}

		[Obsolete("BinaryFormatter.Deserialize is obsolete")]
		public static T ReadBinaryDeserialize<T>(string fileName) where T : class, new()
		{
			if (!File.Exists(fileName))
			{
				return null;
			}
			using FileStream fileStream = new FileStream(fileName, FileMode.Open);
			if (fileStream.Length == 0)
			{
				return null;
			}
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			return binaryFormatter.Deserialize(fileStream) as T;
		}

		public static string GetCodePath([CallerFilePath] string path = null)
		{
			return path;
		}

		public static string GetCodePath<T>([CallerFilePath] string path = null)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return path;
			}
			string result = path;
			string name = typeof(T).Name;
			int num = path.LastIndexOf(name);
			if (num >= 0)
			{
				result = path.Substring(0, num);
			}
			return result;
		}
	}
}
